using GameFrameWork;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace FrameWork
{
    public class GameApp : MonoBehaviour
    {
        private Dictionary<Type, BaseModule> _modules;

        internal static GameApp Instance;

        private void Awake()
        {
            Instance = this;
            _modules = new Dictionary<Type, BaseModule>();
            InitModule();
        }

        /// <summary>
        /// 这里得保证Module顺序
        /// </summary>
        private void InitModule()
        {
            RegisterModule<AudioModule>();
            RegisterModule<EventModule>();
            RegisterModule<TimerModule>();
            RegisterModule<FileModule>();
            RegisterModule<ObjectPoolModule>();
            RegisterModule<ResourceModule>();
            RegisterModule<ConfigModule>();
            RegisterModule<UIModule>();
            RegisterModule<FsmModule>();
            //ProdurceModule----流程Module

            RegisterModule<GameModule>();
        }

        private void Update()
        {
            if (_modules == null || _modules.Count == 0)
                return;

            for (int i = 0; i < _modules.Count; i++)
            {
                KeyValuePair<Type, BaseModule> moduleKeyValuePair = _modules.ElementAt(i);
                BaseModule module = moduleKeyValuePair.Value;
                module.Update(Time.deltaTime, Time.unscaledDeltaTime);
            }
        }

        private void RegisterModule<T>() where T : BaseModule, new()
        {
            Type t = typeof(T);
            if (_modules.ContainsKey(t))
            {
                return;
            }

            T module = new T();
            _modules.Add(t, module);
            module.Init();
        }

        public T GetModule<T>() where T : BaseModule
        {
            if (!_modules.ContainsKey(typeof(T)))
            {
                throw new NullReferenceException("查找不到对应的Module!");
            }

            var module = _modules[typeof(T)];
            return module as T;
        }

        private void OnDestroy()
        {
            ShotDown();
        }

        /// <summary>
        /// 终止
        /// </summary>
        public void ShotDown()
        {
            for (int i = 0; i < _modules.Count; i++)
            {
                KeyValuePair<Type, BaseModule> moduleKeyValuePair = _modules.ElementAt(i);
                BaseModule module = moduleKeyValuePair.Value;
                module.ShutDown();
            }

            _modules.Clear();
            ReferencePool.Release();
        }
    }
}

